#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "tree.h"
extern size_t line_number;

tree new_stmt_node(stmt_kind kind) {
	tree_node * t = (tree_node *)malloc(sizeof(tree_node));
	int i;

	if (!t)
		fprintf(listing,"Out of memory on new_stmt_node() at line %d\n", line_number);
	else {
		for (i=0; i<MAXCHILDREN; i++)
			t->child[i] = 0;
		t->sibling = 0;		/*  */
		t->node_kind = stmtk;
		t->kind.stmt = kind;
		t->lineno = line_number;
	}
	return t;
}


tree new_expr_node(expr_kind kind) {
	tree_node *t = (tree_node *)malloc(sizeof(tree_node));
	int i;
	if (!t)
		fprintf(listing, "Out of memory at new_expr_node() at line:%d\n",line_number);
	else {
		for (i=0; i<MAXCHILDREN; i++) 
			t->child[i] = 0;
		t->sibling	= 0;
		t->lineno	= line_number;
		t->node_kind	= exprk;
		t->kind.expr	= kind;
		t->type		= _void;
	}
	return t;
}


char *str_copy(char *s) {
	char *t;
	if (!s)
		return s;
	t = strdup(s);
	if (!t)
		fprintf(listing,"string copy failure, at line:%d",line_number);
	return t;
}

static  int indentno = 0;	/* for indent the tree with children */
static inline void indent() { indentno += 2;}
static inline void unindent() {indentno -= 2; }

void tree_print(tree thetree) {
	int i;
	indent();
	while (thetree) {
		fprintf(listing,"%*s",indentno,"*"); /* for indent needs */
		if (thetree->node_kind == stmtk) {
			switch(thetree->kind.stmt) {
			default:
				fprintf(listing,"stmt: %d\n",(int)thetree->kind.stmt);
				break;
			}
		} else if (thetree->node_kind == exprk) {
			switch (thetree->kind.expr) {
			case class_key:
				fprintf(listing,"class: %s: \t",(thetree->attr.name)? thetree->attr.name : "<NONAME>");
				switch(thetree->class_attr._access) {
				case _private:
					fprintf(listing,"\tprivate");
					break;
				case _protected:
					fprintf(listing,"\tprotected");
					break;
				case _public:
					fprintf(listing,"\tpublic");
					break;
				}
				if (thetree->class_attr._virtual == _TRUE)
					fprintf(listing,"\tvirtual \n");
				else
					fprintf(listing,"\n");

				break;
				
			case op_key:
				fprintf(listing,"OP: \n");
				/* TODO:
				 * print every operation , */
				break;
			case const_key:
				fprintf(listing,"CONST,%d\n", thetree->attr.val);
				break;
			case id_key:
				fprintf(listing,"ID: %s\n",thetree->attr.name);
				break;
			default:
				fprintf(listing,"Unknown expr kind\n");
				break;
			}
		}
		else
			fprintf(listing,"Unknown node kind\n");

		for (i = 0; i<MAXCHILDREN; i++)
			tree_print(thetree->child[i]);
		thetree = thetree->sibling; /* print the brother nodes */
	}
	unindent();
}
				   
			
		

	
	      

tree add_tree_end(tree t, tree t1)
{
	tree tmp = t;
	if (t) {
		while(t->sibling)
			t = t->sibling;
		t->sibling = t1;
	}
	return tmp;
}


	



